/*! \file
 * \brief Empty.
 * \author Ivo Wingelaar
 * \date 2011
 * \version 0.1.0
 * \copyright GNU Lesser General Public License v3
 */

#include "MythRandom_AlgorithmMotherOfAll_C.hpp"

namespace Myth
{
namespace Random
{

/** constructor **/
/// \param   int32_t seed
///         The seed you want to initialize the generator with.
AlgorithmMotherOfAll_C::AlgorithmMotherOfAll_C( int32_t seed)
{
    random_init(seed);
}

/** default destructor **/
AlgorithmMotherOfAll_C::~AlgorithmMotherOfAll_C()
{
    //
}

/** virtual function **/
/** random_init      **/
//! Initializes the generator with a new seed.
/// \return void
/// \param   int32_t seed
///         The seed to initialize the generator with.
void AlgorithmMotherOfAll_C::random_init( int32_t seed)
{
    uint32_t i;
    uint32_t s = seed;
    for (i = 0; i < 5; i++)
    {
        s = s * 29943829 - 1;
        mX[i] = s;
    }
    for (i=0; i<19; i++) get_random_bytes();
}

/** virtual function **/
/** get_random_bytes **/
//! Return 32 random bits.
/// \return uint32_t
///         32 random bits.
/// \param  void
uint32_t AlgorithmMotherOfAll_C::get_random_bytes(void)
{
    uint64_t sum = (uint64_t)2111111111UL * (uint64_t)mX[3] +
              (uint64_t)1492 * (uint64_t)(mX[2]) +
              (uint64_t)1776 * (uint64_t)(mX[1]) +
              (uint64_t)5115 * (uint64_t)(mX[0]) +
              (uint64_t)mX[4];

    mX[3] = mX[2];
    mX[2] = mX[1];
    mX[1] = mX[0];
    mX[4] = (uint32_t)(sum >> 32);
    mX[0] = (uint32_t)sum;
    return mX[0];
}

} // namespace Random
} // namespace Myth
